<?php

/**
 * CommitLog
 * @description class which queries the SVN using webDAV and caches the output
 * @license http://www.gnu.org/licenses/gpl-2.0.txt     GNU General Public License v3
 * @copyright (C) 2012 by Matej Koval - All rights reserved!
 * @author Matej Koval
 * @website http://www.codegravity.com
 */

// no direct access
defined('_JEXEC') or die('Restricted access');

class CommitLog {

    private $repositoryURL;
    private $repositoryPath;
    private $refreshTime = 100;
    private $maxRecords = 10;

    function __construct($repositoryURL, $repositoryPath, $refreshTime, $maxRecords) {
        $this->repositoryURL = $repositoryURL;
        $this->repositoryPath = $repositoryPath;
        $this->refreshTime = $refreshTime;
        $this->maxRecords = $maxRecords;
    }


    public function render() {
        $logArray = $this->loadFromCache();
        $this->outputArrayWithTemplate($logArray);
    }

    /**
     * checks if cache file exists, then it's time.
     * If it's less than defined refresh time, fetch again latest history from webDAV
     * @return array|mixed
     */
    public function loadFromCache() {
        $cacheFilename = "cache" . DIRECTORY_SEPARATOR . urlencode($this->repositoryURL . $this->repositoryPath);
        $cacheTimestamp = 0;
        if (file_exists($cacheFilename)) {
            $cacheTimestamp = filemtime($cacheFilename);
        }
        if ((time() - $cacheTimestamp) > $this->refreshTime) {
            $logArray = $this->getRemoteHistoryAsArray();
            file_put_contents($cacheFilename, serialize($logArray));
            return $logArray;
        } else {
            $logArray = unserialize(file_get_contents($cacheFilename));
            return $logArray;
        }
    }


    /**
     * renders an array using defined template
     * @param $logArray
     */
    private function outputArrayWithTemplate($logArray) {
        echo("<table>");
        $i=1;
        foreach($logArray as $timestamp => $comment) {
            if ($i > $this->maxRecords) break;
            include("view/resultrow.php");
            $i++;
        }
        echo("</table><br/><br/>");
    }

    /**
     * Returns remote SVN history as associative array of timestamp => comment
     * @return array
     */
    private function getRemoteHistoryAsArray() {
        $xmlElements = $this->getXMLFromRequest();
        $commitArray = array();
        foreach($xmlElements as $logItem) {
            $children = $logItem->children("DAV:");
            $timestamp = strtotime($logItem->date);
            $commitArray[$timestamp] = htmlentities($children->comment);
        }

        krsort($commitArray);
        return $commitArray;
    }



    /**
     * function which parses the response returned by webDAV and creates
     * an SimpleXMLElement object for further parsing
     * @return SimpleXMLElement
     */
    private function getXMLFromRequest() {
        $body = $this->getResponse();
        $body = substr($body, strpos($body, "<"));
        $body = substr($body, 0, strrpos($body, ">")+1);
        return @new SimpleXMLElement($body, 0, false, "svn:");
    }

    /**
     * queries the SVN webDAV in order to get the response
     * @return string
     */
    private function getResponse() {
        require_once("lib/http.php");
        $http = new http_class;
        $arguments = $this->createRequestArguments();

        $http->Open($arguments);
        $http->SendRequest($arguments);
        $body = "";
        $http->ReadReplyBody($body, 9999999999999);
        $http->Close();
        return $body;
    }

    /**
     * function which constructs the request to be sent using http client library
     * @return array
     */
    private function createRequestArguments() {
        $SVN_WEBDAV_REQUEST = '<?xml version="1.0"?>'.
            '<S:log-report xmlns:S="svn:">'.
            '<S:start-revision>%d</S:start-revision>'.
            '</S:log-report>';

        $request = sprintf($SVN_WEBDAV_REQUEST, 0);

        $urlParsed = parse_url($this->repositoryURL);
        $arguments["Protocol"] = $urlParsed['scheme'];
        $arguments["HostName"] = $urlParsed['host'];
        $arguments["Headers"]["Host"] = $urlParsed['host'];
        $arguments["Headers"]["User-Agent"] = "test";
        $arguments["Headers"]["Authorization"] = "Basic Og==";
        $arguments["Headers"]["Content-Type"] = "text/xml";
        $arguments["Headers"]["Depth"] = 1;
        $arguments["Headers"]["Content-Length"] = strlen($request);

        $arguments["HostPort"] = 0;
        $arguments["RequestURI"] = $this->repositoryPath;
        $arguments["RequestMethod"] = "REPORT";

        $arguments["Body"] = $request;
        return $arguments;
    }

}
?>